home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
fviewsrc.zip
/
FOSCOM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-04
|
16KB
|
556 lines
/*--------------------------------------------------------------------------*/
/* */
/* Copyright 1989, Doug Boone FidoNet 119/5 */
/* Copyright 1989, John Valentyn FidoNet 114/18 */
/* */
/* (916) 893-9019 Data */
/* (916) 891-0748 voice */
/* P.O. Box 5108, Chico, CA. 95928 */
/* */
/* Originally by John Vallentyn (FidoNet 114/15), so you'll need his */
/* permission too. */
/* */
/* This program is not for sale. It is for the free use with Opus systems. */
/* You may not sell it in ANY way. If you have an access charge to your */
/* Bulletin Board, consider this to be like Opus, you can ONLY make it */
/* available for download in an open area, where non-members can get access */
/* */
/* If you need to modify this source code, please send me a copy of the */
/* changes you've made so that everyone can share in the updates. */
/* */
/* "Don't rip me off!" -- Tom Jennings, FidoNet's founder */
/* */
/*--------------------------------------------------------------------------*/
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <dos.h>
#include <conio.h>
#include <stdarg.h>
#include <stdlib.h>
#ifdef TURBOC
#include <alloc.h>
#include <sys\timeb.h>
#else
#include <malloc.h>
#endif
#include "archdr.h"
extern int baud;
extern int port;
extern int flags;
extern int line;
extern int screen;
extern int ctrl_err;
extern long quit_time;
extern int (cdecl * cdecl sdisplay)(char *); /* ptr to display function */
extern int (cdecl * cdecl get_a_char)(void); /* instead of getch() */
extern int (cdecl * cdecl chk_keyboard)(void); /* instead of kbhit() */
int GetDriverInfo(void);
int CkFossilCD(void);
int Com_(unsigned,unsigned);
int Comm_Set_Baud(int,int,int,int);
void Comm_transmit(int);
int Comm_Receive(void);
int Get_Comm_Status(void);
int Comm_Char_Avail(void);
int Comm_Init(int,int,int,int);
void Comm_De_Init(void);
void Comm_Dtr(int);
void Comm_flush_out(void);
void Comm_Purge_out(void);
void Comm_Purge_in(void);
void Comm_Watch(int);
char Comm_Peek(void);
int Comm_CD(void);
int locputs(register char *);
int fosputs(register char *);
int play(const char *,...);
void sendbyte(byte);
void ask_more(void);
extern void terminate(int);
struct fos_info { /* info avail via 0x1B function */
int info_size; /* Offset 0 (word) = Structure size */
char fos_spec; /* 2 (byte) = FOSSIL spec version */
char drvr_rev; /* 3 (byte) = Driver rev level */
char far *fos_id; /* 4 (dwrd) = Pointer to ASCII ID */
int ibuf_sz; /* 8 (word) = Input buffer size */
int ibuf_free; /* 0A (word) = Bytes avail (input) */
int obuf_sz; /* 0C (word) = Output buffer size */
int obuf_free; /* 0E (word) = Bytes avail (output) */
char scrn_width; /* 10 (byte) = Screen width, chars */
char scrn_height; /* 11 (byte) = Screen height, chars */
char baud_msk; /* 12 (byte) = Baud rate mask */
} fossil_info =
{ 0, 0, 0, 0L, 0, 0, 0, 0, 0, 0, 0 };
/* ====================================================================
* Fill in the fossil information block
* ====================================================================
*/
int GetDriverInfo(void)
{
union REGS regs;
struct SREGS segregs;
int result;
char far *p;
p = (char far *) &fossil_info;
regs.h.al = 0;
regs.h.ah = 0x1B; /* function = get driver info */
regs.x.cx = sizeof(struct fos_info);
regs.x.di = FP_OFF (p);
segregs.es = segregs.ds = FP_SEG (p);
regs.x.dx = port;
result=int86x(FOSSIL_INT, ®s, ®s, &segregs);
return(result);
}
/* ====================================================================
* CkFossilCD() -- Check if Fossil initiallized and CD on
* ====================================================================
*/
int CkFossilCD(void)
{
union REGS regs;
long far *INTword;
int far *IDword;
INTword = (long far *) 0x50; /* get interrupt pointer for INT 14h function */
IDword = (int far *) *INTword+3; /* point to sig word 1954 and add offset */
if(*IDword != 0x1954) { /* if FOSSIL not installed */
printf("FOSSIL not installed...\n");
return(FALSE);
}
regs.h.al = 0;
regs.h.ah = 0x04; /* function = initialize driver */
regs.x.dx = port;
regs.x.bx = 0; /* no ^C */
int86(FOSSIL_INT, ®s, ®s);
if(regs.x.ax != 0x1954)
return(FALSE); /* unable to initialize fossil */
if (flags & FOSSIL) {
Comm_Dtr(1); /* insure that DTR is on */
return(Get_Comm_Status() & DCD); /* return DCD */
}
else
return(TRUE);
}
/* ====================================================================
* General purpose comm function
* ====================================================================
*/
int Com_(unsigned funct,unsigned chr)
{
union REGS regs;
int result;
regs.h.al = (byte)chr;
regs.h.ah = (byte)funct;
regs.x.dx = port;
result=int86(FOSSIL_INT, ®s, ®s);
return(result);
}
/* ====================================================================
* fossil function 0 = Set baud rate
* ====================================================================
*/
int Comm_Set_Baud(int BaudRate,
int DataBits,
int StopBits,
int Parity)
{
union REGS regs;
register int value;
switch(BaudRate/300) {
case 1: value = 0x40; break;
case 2: value = 0x60; break;
case 4: value = 0x80; break;
case 8: value = 0xA0; break;
case 16: value = 0xC0; break;
case 32: value = 0xE0; break;
case 64: value = 0; break;
default: return(FALSE);
}
switch (Parity) {
case 0: break;
case 1: value |= 0x8; break;
case 2: value |= 0xA; break;
default: return(FALSE);
}
switch(StopBits-1) {
case 0: break;
case 1: value |= 0x4; break;
default: return(FALSE);
}
switch (DataBits-7) {
case 0: value |= 0x2; break;
case 1: value |= 0x3; break;
default: return(FALSE);
}
regs.h.ah = 0x00;
regs.h.al = (byte)value;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
return(TRUE);
}
/* ====================================================================
* fossil function 1 - transmit character with wait
* ====================================================================
*/
void Comm_transmit(int chr)
{
union REGS regs;
regs.h.ah = 0x01;
regs.h.al = (byte)chr;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
return;
}
/* ====================================================================
* fossil function 2 - receive character with wait
* ====================================================================
*/
int Comm_Receive(void)
{
union REGS regs;
do { /* Watch carrier while waiting for next charatcher */
if (Comm_CD() == FALSE)
terminate(3);
if (kbhit()) /* Allows local keyboard over-ride */
return(getch());
} while (Comm_Peek() == 0xff);
regs.h.ah = 0x02;
regs.h.al = 0x00;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
regs.h.ah = 0x00;
return(regs.x.ax);
}
/* ====================================================================
* get status of comm port
* ====================================================================
*/
int Get_Comm_Status(void)
{
union REGS regs;
regs.h.ah = 0x03; /* function = request status */
regs.h.al = 0x00;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
if (!(regs.x.ax & DCD) && flags & FOSSIL)
terminate(3);
if (regs.x.ax == 0xffff) /* Hangs sometimes clear buffer */
Comm_Purge_out();
return(regs.x.ax);
}
/* ====================================================================
* check if character available in input buffer
* ====================================================================
*/
int Comm_Char_Avail(void)
{
union REGS regs;
regs.h.ah = 0x03; /* function = request status */
regs.h.al = 0x00;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
regs.x.ax = regs.x.ax & 0x0100; /* check input data avail, ah bit 0 */
if (regs.x.ax == 0)
return(FALSE);
return(TRUE);
}
/* ====================================================================
* function 4 - initialize driver
* ==================================================================== */
int Comm_Init(int BaudRate,
int DataBits,
int StopBits,
int Parity)
{
union REGS regs;
regs.h.ah = 0x04;
regs.h.al = (byte)(BaudRate | DataBits | StopBits | Parity);
regs.x.dx = port;
regs.x.bx = 0; /* no ^C code */
int86(FOSSIL_INT, ®s, ®s);
return(regs.x.ax);
}
/* ====================================================================
* function 5 - deinitialize driver
* ====================================================================
*/
void Comm_De_Init(void)
{
union REGS regs;
regs.h.ah = 0x05;
regs.h.al = 0;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
return;
}
/* ====================================================================
* function 6 - Raise/Lower DTR
* ====================================================================
*/
void Comm_Dtr(int flag)
{
union REGS regs;
regs.h.ah = 0x06;
regs.h.al = (byte)flag; /* 01h=Raise 00h=Lower */
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
return;
}
/* ====================================================================
* function 8 - flush output buffer
* ====================================================================
*/
void Comm_flush_out(void)
{
union REGS regs;
regs.h.ah = 0x08;
regs.h.al = 0x00;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
return;
}
/* ====================================================================
* function 9 - purge output buffer
* ====================================================================
*/
void Comm_Purge_out(void)
{
union REGS regs;
regs.h.ah = 0x09;
regs.h.al = 0x00;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
return;
}
/* ====================================================================
* function 10 (0Ah) - purge input buffer
* ====================================================================
*/
void Comm_Purge_in(void)
{
union REGS regs;
regs.h.ah = 0x0A;
regs.h.al = 0x00;
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
return;
}
/* ====================================================================
* function 14 - Watchdog On/Off
* ====================================================================
*/
void Comm_Watch(int flag)
{
union REGS regs;
regs.h.ah = 0x14;
regs.h.al = (byte)flag; /* 01h=Watchdog on 00h=Watchdog off */
regs.x.dx = port;
int86(FOSSIL_INT, ®s, ®s);
return;
}
/*--------------------------------------------------------------------------*/
/* Look ahead at input buffer, primarily to check for ^C */
/*--------------------------------------------------------------------------*/
char Comm_Peek(void)
{
union REGS regs;
regs.h.ah = 0x0C;
regs.x.dx = port;
int86(FOSSIL_INT, ®s,®s);
return(regs.h.al);
}
/* ====================================================================
* Check for carrier detect returns TRUE (1) while carrier is high
* ====================================================================
*/
int Comm_CD(void)
{
union REGS regs;
regs.h.ah = 0x03;
regs.x.dx = port;
int86(FOSSIL_INT, ®s,®s);
if (regs.h.al & DCD)
return(TRUE);
else
return(FALSE);
}
/* ====================================================================
* Local display function - access via display()
* ====================================================================
*/
int locputs(register char *str)
{
register int c;
while (*str && ctrl_err) {
c = *str++;
putchar(c);
if (c == '\n')
line++;
if (line > (screen-2) && flags & MORE)
ask_more();
}
return(0);
}
/* ====================================================================
* Fossil display function - access via display()
* ====================================================================
*/
int fosputs(register char *str)
{
register int c;
while (*str && ctrl_err) {
c = *str++;
putchar(c); /* So what's going on will display locally!! */
if(c == '\n') {
Comm_transmit('\r');
line++;
if (Comm_Peek() == 0x13) {
Comm_Purge_in();
while (Comm_Peek() == 0xff);
Comm_Purge_in();
}
else if (Comm_Peek() == 0x03) {
Comm_Purge_in();
Comm_Purge_out();
ctrl_err = 0;
}
}
Comm_transmit(c);
if (line > (screen-2) && flags & MORE)
ask_more();
}
while(!(Get_Comm_Status() & TSRE)); /* wait for output buffer to empty */
return(0);
}
/* ====================================================================
* display is a printf function to either the console or the comm port
* note that the argument is variable (therefore must be cdecl convention)
* ====================================================================
*/
int play(const char *fmt,...)
{
char pbuf[BUFSIZ];
va_list arg_ptr;
va_start(arg_ptr, fmt);
vsprintf(pbuf, fmt, arg_ptr);
va_end(arg_ptr);
sdisplay(pbuf);
return(0);
}
/* ====================================================================
* sendbyte outputs a character to either the console or the comm port
* ====================================================================
*/
void sendbyte(byte ch)
{
if(flags & FOSSIL) {
if(ch == '\n') {
Comm_transmit('\r');
line++;
if (!(Comm_CD()))
terminate(3);
}
Comm_transmit(ch);
putchar(ch);
while(!(Get_Comm_Status() & TSRE)); /* wait for output buffer to empty */
return;
}
else
putchar(ch);
return;
}
/*--------------------------------------------------------------------------*/
/* If user has More? on in their user record */
/*--------------------------------------------------------------------------*/
void ask_more(void)
{
char ch;
line = 0;
if (quit_time < time(NULL)) /* Check the time */
ctrl_err = 0;
if (flags & FOSSIL) { /* Check carrier, exit(3) if lost */
if (!(Comm_CD()))
terminate(3);
if (Comm_Peek() == 0x03) { /* Check for ^C inbound buffer */
ctrl_err = 0;
Comm_Purge_in(); /* Clear all buffers */
Comm_Purge_out();
}
}
sdisplay("More [Y,n,=]? ");
ch = get_a_char();
sdisplay("\n");
switch(ch) {
case '\03':
case 'n':
case 'N': ctrl_err = 0;
return;
case '=':
case '+': flags &= ~MORE;
break;
default: break;
}
return;
}